package com.prpat;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;

import de.uniba.wiai.lspi.util.console.Command;

/**
 * A thread that finds the Node's successor and sends a 
 * {@link Message} to it
 * @author sas
 *
 */
class Sender// implements Runnable
{
	static Socket socket;
	static ObjectOutputStream reader;

	/**String holding the IP of the Node that will receive */
	static String destination = null;

	public static void init()
	{
		extractSuccessor();
	}

	public static void sendMessage(Message mes){
		synchronized (Sender.class) {
			try {
				extractSuccessor();
				socket = new Socket(destination, River.CHAT_PORT);
				socket.setTcpNoDelay(true); 
				reader = new ObjectOutputStream(socket.getOutputStream());
				reader.writeObject(mes);
				reader.flush();
				reader.close();

				socket.close();

				String type = mes.getType() == Message.REQUEST ? "REQUEST"
						: "REPLY";

//				River.display.append("Sending to " + destination
//						+ " the following " + type + "\n");
//				River.display.append(mes.toString() + "\n\n");
				System.out.println("Sending to " + destination
						+ " the following " + type + "\n" + mes.toString() + "\n\n");
			} catch (IOException ex) {
				System.err.println("Sender, run(), ex" + ex.toString());

//				if(ex instanceof ConnectException){
//					extractSuccessor();
//					if(destination == null){
//						River.CONNECTED = false;
//						River.ocExecuted("leaveN");
//						River.connectionRenewer();
//					}
//				}
				//TODO handle disconnection
			}
		}

	}

	public static void replyToBootstrap(Message mes){
		synchronized (Sender.class) {
			try {
				socket = new Socket(River.BOOTSTRAP, River.CHAT_PORT);
				socket.setTcpNoDelay(true); 
				reader = new ObjectOutputStream(socket.getOutputStream());
				reader.writeObject(mes);
				reader.flush();
				reader.close();

				socket.close();

				String type = mes.getType() == Message.REQUEST ? "REQUEST"
						: "REPLY";

//				River.display.append("Sending to " + destination
//						+ " the following " + type + "\n");
//				River.display.append(mes.toString() + "\n\n");
				System.out.println("Sending to BOOTSTRAP"
						+ " the following " + type + "\n" + mes.toString() + "\n\n");
			} catch (IOException ex) {
				System.err.println("Sender, run(), ex" + ex.toString());

//				if(ex instanceof ConnectException){
//					extractSuccessor();
//					if(destination == null){
//						River.CONNECTED = false;
//						River.ocExecuted("leaveN");
//						River.connectionRenewer();
//					}
//				}
				//TODO handle disconnection
			}
		}

	}

	/**
	 * checks the IP of this Node's successor and assigns it to {@link destination}
	 */
	private static void extractSuccessor() 
	{
		String str;
		while(true){
			try 
			{
				Command com = River.factory.createCommand("find");
				com.execute();
				str = com.toString();

				if(str != null)
				{
					str = str.substring(str.indexOf("//")+2, str.lastIndexOf("/"));
					if(str.contains(":"))
						str = str.substring(0, str.indexOf(":"));
					destination = str;
//					System.err.println("Successor Found");
					break;
				}
				else
				{
					synchronized (Sender.class) 
					{
						try 
						{
							double d = Math.log(1-Math.random())*(-1000);
							Sender.class.wait((new Double(d)).longValue());
//							Sender.class.wait(1000);
						} 
						catch (Exception e) {}
					}
					//River.display.append("This Node doesn't have successors\n");
				}
			}
			catch (Exception e) {
				destination = null;
				System.err.println("Sender, extractSuccessor(), "+e.getMessage());

			}
		}

	}
	
//	private static void getSuccessor(){
//		String str;
//		try 
//		{
//			Command com = River.factory.createCommand("find");
//			com.execute();
//			str = com.toString();
//
//			if(str != null)
//			{
//				str = str.substring(str.indexOf("//")+2, str.lastIndexOf("/"));
//				if(str.contains(":"))
//					str = str.substring(0, str.indexOf(":"));
//				destination = str;
////				System.err.println("Successor Found");
//			}
//			else{
//				destination = River.BOOTSTRAP;
//			}
//
//		}
//		catch (Exception e) {
//			destination = River.BOOTSTRAP;
//			System.err.println("Sender, extractSuccessor(), "+e.getMessage());
//
//		}
//	}
	
}
